package com.gitee.wsl.transform.format.number

/**
 * Defines the type of number representation
 * [EXPONENT], [FIXED_POINT],
 * [PERCENT], [PERCENT_ROUNDED],
 * [DECIMAL], [DECIMAL_ROUNDED], [DECIMAL_WITH_SI], [DECIMAL_OR_EXPONENT],
 * [BINARY], [OCTAL], [HEX_LOWERCASE], [HEX_UPPERCASE],
 * [CHAR].
 * Defaults to [NONE]
 */
 enum class Type(internal val c: String) {

    /**
     * like [DECIMAL_OR_EXPONENT], but trim insignificant trailing zeros.
     */
    NONE(" "),

    /**
     * decimal notation, rounded to significant digits.
     */
    DECIMAL("r"),

    /**
     * decimal notation, rounded to integer.
     */
    DECIMAL_ROUNDED("d"),

    /**
     * decimal notation with an [SI prefix][Locale.formatPrefix], rounded to significant digits.
     */
    DECIMAL_WITH_SI("s"),

    /**
     * either decimal or exponent notation, rounded to significant digits.
     */
    DECIMAL_OR_EXPONENT("g"),

    /**
     * Exponent notation
     */
    EXPONENT("e"),

    /**
     * Fixed point notation
     */
    FIXED_POINT("f"),

    /**
     * multiply by 100, and then decimal notation with a percent sign.
     */
    PERCENT("%"),

    /**
     * multiply by 100, round to significant digits, and then decimal notation with a percent sign
     */
    PERCENT_ROUNDED("p"),

    /**
     * binary notation, rounded to integer.
     */
    BINARY("b"),

    /**
     * octal notation, rounded to integer.
     */
    OCTAL("o"),

    /**
     * hexadecimal notation, using lower-case letters, rounded to integer.
     */
    HEX_LOWERCASE("x"),

    /**
     * hexadecimal notation, using upper-case letters, rounded to integer.
     */
    HEX_UPPERCASE("X");

    /**
     * converts the integer to the corresponding unicode character before printing.
     */
//    CHAR("c");

    /**
     * @suppress
     */
    override fun toString(): String = if (this == NONE) "" else c
}

/**
 * Check if it is a number based type (binary, octal, hex ie: boxX)
 */
internal val Type?.isNumberBase: Boolean
    get() =
        (this != null &&
                (this == Type.BINARY ||
                        this == Type.OCTAL ||
                        this == Type.HEX_UPPERCASE ||
                        this == Type.HEX_LOWERCASE))

/**
 * Check if it is a percent type (%p)
 */
internal val Type?.isPercent: Boolean
    get() =
        (this != null && (
                this == Type.PERCENT ||
                        this == Type.PERCENT_ROUNDED))
internal val Type?.maybeSuffix: Boolean
    get() =
        (this != null && (
                this == Type.DECIMAL_ROUNDED ||
                        this == Type.EXPONENT ||
                        this == Type.FIXED_POINT ||
                        this == Type.DECIMAL_OR_EXPONENT ||
                        this == Type.PERCENT_ROUNDED ||
                        this == Type.DECIMAL ||
                        this == Type.DECIMAL_WITH_SI ||
                        this == Type.PERCENT
                ))
internal val gprs = listOf(
    Type.DECIMAL_OR_EXPONENT,
    Type.PERCENT_ROUNDED,
    Type.DECIMAL,
    Type.DECIMAL_WITH_SI
)